using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Globalization;
using System.Windows;
using System.IO;
using System.Threading;
using Level65.ClipShow;

namespace Level65.WMVHelper
{
    public class ThumbnailEventArgs : EventArgs
    {
        private string _eventText;

        public ThumbnailEventArgs(string eventText)
        {
            _eventText = eventText;
        }

        public string ThumbnailEventText
        {
            get
            {
                return (_eventText);
            }
        }
    }

    public delegate void ThumbnailEventHandler(object sender, ThumbnailEventArgs e);

    public class Thumbnail
    {
        private ArrayList _mediaPayload;
        private MediaPlayer _mp;
        public Thumbnail()
        {

        }

        public Thumbnail(ArrayList source, MediaPlayer mp)
        {
            _mediaPayload = source;
            _mp = mp;
        }
        public event ThumbnailEventHandler ThumbnailAlert;
        protected virtual void OnThumbnailAlert(ThumbnailEventArgs e)
        {
            if (ThumbnailAlert != null)
            {
                // Invokes the delegates. 
                ThumbnailAlert(this, e);
            }
        }

        private bool IsThumbnailException(string sourceFilePath)
        {
            bool result = false;
            string fileExtension = Path.GetExtension(sourceFilePath).ToLower();
            switch (fileExtension)
            {
                default: result = false; break;
                case ".mov": result = true; break;
                case ".mp4": result = true; break;
                case ".mts": result = true; break;
                case ".m2ts": result = true; break;
                case ".m2t": result = true; break;
            }
            return (result);
        }

        internal static void CreateImageThumbnail(ThumbnailPayloadItem tp)
        {
            FormattedText fte = new FormattedText(tp.Title.ToUpper(), CultureInfo.GetCultureInfo("en-us"), 
                FlowDirection.LeftToRight,
                new Typeface("Segoe UI"), 48, Brushes.White);
            fte.MaxTextHeight = 240;
            fte.MaxTextWidth = 320;
            fte.TextAlignment = TextAlignment.Left;

            RenderTargetBitmap rtb = new RenderTargetBitmap(320, 240, 1 / 200, 1 / 200, PixelFormats.Default);
            DrawingVisual dv = new DrawingVisual();
            Pen shapeOutlinePen = new Pen(Brushes.Black, 2);
            shapeOutlinePen.Freeze();
            DrawingContext dc = dv.RenderOpen();
            
            dc.DrawRectangle(Brushes.SteelBlue, shapeOutlinePen, new Rect(0, 0, 320, 240));
            dc.DrawText(fte, new Point(0,5));
            dc.Close();
            rtb.Render(dv);

            // Now persist the file
            BitmapSource bitmap = BitmapFrame.Create(rtb);
            if (bitmap != null)
            {
                JpegBitmapEncoder jpeg = new JpegBitmapEncoder();
                jpeg.Frames.Add(BitmapFrame.Create(bitmap));

                using (Stream stm = File.Create(tp.ThumbnailTargetFilePath))
                {
                    jpeg.Save(stm);
                }
            }
        }

        public bool BuildThumbnails(bool extractThumbnails)
        {
            int thumbNailCtr = 0;
            foreach (ThumbnailPayloadItem tp in _mediaPayload)
            {
                // Limit building thumbnails to 100 at a time if extracting from media item
                if ( (thumbNailCtr >= 100) && (extractThumbnails))
                {
                    break;
                }
                if (File.Exists(tp.SourceMediaFilePath))
                {
                    if (!File.Exists(tp.ThumbnailTargetFilePath))
                    {
                        if (IsThumbnailException(tp.SourceMediaFilePath))
                        {
                            // MOV,MP4, MTS variety files will be excluded for this release; create the title thumbnail instead
                            CreateImageThumbnail(tp);
                        }
                        else
                        {
                            if (extractThumbnails)
                            {
                                TimeSpan ts = new TimeSpan();
                                if (tp.StartFrame.Equals(0))
                                {
                                    Random r = new Random(unchecked((int)DateTime.Now.Ticks));
                                    ts = new TimeSpan(0, 0, r.Next(10, 45));
                                }
                                else
                                {
                                    ts = new TimeSpan(0, 0, tp.StartFrame);
                                }
                                #region Grab thumbnail using WMPlayer
                                try
                                {
                                    _mp.Stop();
                                    _mp.Open(new Uri(tp.SourceMediaFilePath));
                                    _mp.Volume = 0;
                                    _mp.Position = ts;
                                    _mp.Play();

                                    // Wait for media buffering
                                    Thread.Sleep(4000);

                                    // Grab the clip image
                                    RenderTargetBitmap rtb = new RenderTargetBitmap(320, 240, 1 / 200, 1 / 200, PixelFormats.Pbgra32);
                                    DrawingVisual dv = new DrawingVisual();
                                    DrawingContext dc = dv.RenderOpen();
                                    dc.DrawVideo(_mp, new Rect(0, 0, 320, 240));
                                    dc.Close();
                                    rtb.Render(dv);

                                    // Now persist the file
                                    BitmapSource bitmap = BitmapFrame.Create(rtb);
                                    if (bitmap != null)
                                    {
                                        JpegBitmapEncoder jpeg = new JpegBitmapEncoder();
                                        jpeg.Frames.Add(BitmapFrame.Create(bitmap));

                                        using (Stream stm = File.Create(tp.ThumbnailTargetFilePath))
                                        {
                                            jpeg.Save(stm);
                                        }
                                    }
                                    _mp.Stop();
                                }
                                catch
                                {
                                    // Punt with a thumbnail of the title
                                    CreateImageThumbnail(tp);
                                }
                                #endregion
                            }
                            else
                            {
                                // Build a thumbnail with only the title
                                CreateImageThumbnail(tp);
                            }

                            // Now alert the outside world we now have a thumbnail
                            ThumbnailEventArgs e = new ThumbnailEventArgs(tp.ThumbnailTargetFilePath);
                            OnThumbnailAlert(e);
                            thumbNailCtr++;
                        }
                    }
                }
            }

            if (thumbNailCtr < 100)
            {
                // Flush the payload list
                _mediaPayload.Clear();
            }
            return (thumbNailCtr==100);
        }
    }
}
